package com.cloudeasy.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudeasy.api.enums.ResultCodeEnum;
import com.cloudeasy.api.exception.CloudEasyException;
import com.cloudeasy.user.constant.UserRoleConstant;
import com.cloudeasy.user.dto.UserRoleDTO;
import com.cloudeasy.user.mapper.UserRoleMapper;
import com.cloudeasy.user.po.UserRole;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class UserRoleService extends ServiceImpl<UserRoleMapper, UserRole> {
    private final UserService userService;

    private final RoleService roleService;

    public UserRoleService(UserService userService, RoleService roleService) {
        this.userService = userService;
        this.roleService = roleService;
    }

    /**
     * 获取用户的角色
     *
     * @param userId 用户Id
     * @return {@link List<UserRole>}
     */
    public List<UserRole> listByUserId(String userId) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return this.list(queryWrapper);
    }

    /**
     * 分配角色，若已存在，则不进行处理
     *
     * @param userId 用户Id
     * @param roleId 角色Id
     * @return {@link Boolean}
     */
    public Boolean distribute(String userId, String roleId) {
        UserRole userRole = UserRole.builder()
                .userId(userId)
                .roleId(roleId)
                .build();
        return this.save(userRole);
    }

    /**
     * 保存用户角色关联信息
     *
     * @param userId      用户Id
     * @param roleId      角色Id
     * @param userRoleDTO {@link UserRoleDTO}
     * @return {@link Boolean}
     */
    public Boolean save(String userId, String roleId, UserRoleDTO userRoleDTO) {
        if (roleService.getById(roleId) == null || userService.getById(userId) == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        if (getByUserIdAndRoleId(userId, roleId) != null) {
            throw new CloudEasyException(ResultCodeEnum.REPEAT_ERROR);
        }
        UserRole userRole = UserRole.builder().userId(userId).roleId(roleId).build();
        BeanUtils.copyProperties(userRoleDTO, userRole);
        return this.save(userRole);
    }


    /**
     * 获取用户具有多个角色的记录
     *
     * @param userId  用户Id
     * @param roleIds 角色Id列表
     * @return {@link List<UserRole>}
     */
    public List<UserRole> listByUserIdAndRoleIds(String userId, List<String> roleIds) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .in("role_id", roleIds);
        return this.list(queryWrapper);
    }

    /**
     * 通过用户Id和角色Id更新用户角色记录
     *
     * @param userId      用户Id
     * @param roleId      角色Id
     * @param userRoleDTO {@link UserRoleDTO}
     * @return {@link Boolean}
     */
    public Boolean updateByUserIdAndRoleId(String userId, String roleId, UserRoleDTO userRoleDTO) {
        UserRole userRole = this.getByUserIdAndRoleId(userId, roleId);
        if (userRole == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        BeanUtils.copyProperties(userRoleDTO, userRole);
        UpdateWrapper<UserRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("user_id", userId)
                .eq("role_id", roleId);
        return this.update(userRole, updateWrapper);
    }

    /**
     * 通过用户Id和角色Id删除用户角色记录
     *
     * @param userId 用户Id
     * @param roleId 角色Id列表
     * @return {@link List<UserRole>}
     */
    public Boolean removeByUserIdAndRoleIds(String userId, String roleId) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .in("role_id", roleId);
        return this.remove(queryWrapper);
    }

    /**
     * 改变角色管理区域
     *
     * @param rawAreaName    原始区域名称
     * @param targetAreaName 目标区域名称
     * @return {@link Boolean}
     */
    public Boolean changeOperateArea(String rawAreaName, String targetAreaName) {
        UpdateWrapper<UserRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("operate_area", targetAreaName)
                .set("with_self", false)
                .set("level", UserRoleConstant.LEVEL_MIN)
                .eq("operate_area", rawAreaName);
        return this.update(updateWrapper);
    }

    /**
     * 通过用户Id和角色Id获取用户角色记录
     *
     * @param userId 用户Id
     * @param roleId 角色Id
     * @return {@link UserRole}
     */
    public UserRole getByUserIdAndRoleId(String userId, String roleId) {
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                .eq("role_id", roleId);
        return this.getOne(queryWrapper);
    }

    /**
     * 解除锁定
     */
    public void unlocked() {
        UpdateWrapper<UserRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("status", UserRoleConstant.LOCKING)
                .lt("recovery_time", new Date())
                .set("status", UserRoleConstant.NORMAL)
                .set("recovery_time", null);
        this.update(updateWrapper);
    }
}
